package com.cf.apiInstance.common.utils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * 时间处理类
 * 
 * @author: cf
 * @date: 30 Nov 2018 11:43:39 am
 * @vesion: 1.0
 */
@Slf4j
public class DateUtils {

	/**
	 * 日期格式 *
	 */
	public interface DATE_PATTERN {

		String HHMMSS = "HHmmss";
		String HH_MM_SS = "HH:mm:ss";
		String YYYY = "yyyy";
		String YYYYMM = "yyyyMM";
		String YYYYMMDD = "yyyyMMdd";
		String YYYY_MM = "yyyy-MM";
		String YYYY_MM_DD = "yyyy-MM-dd";
		String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
		String YYYYMMDDHHMMSSSSS = "yyyyMMddHHmmssSSS";
		String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
	}

	/**
	 * 取得昨天此时的时间
	 * 
	 * @return 返回类型 Date
	 */
	public static Date getYesterdayDate() {
		return new Date(System.currentTimeMillis() - 0x5265c00L);
	}

	/**
	 * 获取上周开始时间
	 * 
	 * @return 返回类型 Date
	 */
	public static Date getLastWeekStart() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.DATE, -7);
		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTime();
	}

	/**
	 * 获取本周开始时间
	 * 
	 * @return 返回类型 Date
	 */
	public static Date getThisWeekStart() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.DATE, 0);
		cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTime();
	}

	/**
	 * 获取今天开始时间
	 * 
	 * @return 返回类型 Date
	 */
	public static Date getThisDayStart() {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal.getTime();
	}

	/**
	 * 获取本月开始时间
	 * 
	 * @return 返回类型 Date
	 */
	public static Date getThisMonthStart() {
		Calendar cal = Calendar.getInstance();
		cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
		cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
		return cal.getTime();
	}

	/**
	 * 获取本月结束时间
	 * 
	 * @return 返回类型 Date
	 */
	public static Date getThisMonthEnd() {
		Calendar cal = Calendar.getInstance();
		cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONDAY), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
		cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
		cal.set(Calendar.HOUR_OF_DAY, 23);
		cal.set(Calendar.MINUTE, 59);
		cal.set(Calendar.SECOND, 59);
		return cal.getTime();
	}

	/**
	 * 获取上月开始时间
	 * 
	 * @return 返回类型 Date
	 */
	public static Date getLastMonthStart() {
		Calendar cal = Calendar.getInstance();
		cal.setTime(getThisMonthStart());
		cal.add(Calendar.MONTH, -1);
		return cal.getTime();
	}

	/**
	 * 获取过期几个月的开始时间
	 * 
	 * @return 返回类型 Date
	 */
	public static Date getLastMonthStart(int passMonth) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(getThisMonthStart());
		cal.add(Calendar.MONTH, -passMonth);
		return cal.getTime();
	}

	/**
	 * 上月结束时间
	 * 
	 * @return 返回类型 Date
	 */
	public static Date getLastMonthEnd() {
		Calendar cal = Calendar.getInstance();
		cal.setTime(getThisMonthEnd());
		cal.add(Calendar.MONTH, -1);
		return cal.getTime();
	}

	public static Date parse(String date, SimpleDateFormat format) {
		if (StringUtils.isEmpty(date)) {
			return null;
		}
		try {
			return format.parse(date);
		} catch (ParseException e) {
			log.error(e.getMessage(), e);
			return null;
		}
	}

	/**
	 * 取得去过i天的时间
	 * 
	 * @param i
	 *            过去时间天数
	 * @return 昨天日期（Date）
	 */
	public static Date getPastdayDate(int i) {
		return new Date(System.currentTimeMillis() - 0x5265c00L * i);
	}

	public static Date getPastdayDate(Date date, int i) {
		return new Date(date.getTime() - 0x5265c00L * i);
	}

	/**
	 * 取得未来i天的结束时间
	 * 
	 * @param i
	 *            加时间天数
	 * @return 结束日期（Date）
	 */
	public static Date getLaterdayDate(int i) {
		return new Date(System.currentTimeMillis() + 0x5265c00L * i - 1);
	}

	public static Date getLaterdayDate(Date date, int i) {
		return new Date(date.getTime() + 0x5265c00L * i - 1);
	}

	/**
	 * 取得某日期时间的特定表示格式的字符串
	 * 
	 * @param format
	 *            时间格式
	 * @param date
	 *            某日期（Date）
	 * @return 某日期的字符串
	 */
	public static synchronized String format(Date date, String format) {
		SimpleDateFormat ft = new SimpleDateFormat(format);
		return ft.format(date);
	}

	/**
	 * 取得某日期时间的特定表示格式的字符串
	 * 
	 * @param format
	 *            时间格式
	 * @param date
	 *            某日期（Date）
	 * @return 某日期的字符串
	 */
	public static synchronized String format(Date date, DateFormat format) {
		return format.format(date);
	}

	/**
	 * 以分钟的形式表示两个长整型数表示的时间间隔
	 * 
	 * @param from
	 *            开始的长整型数据
	 * @param to
	 *            结束的长整型数据
	 * @return 相隔的分钟数
	 */
	public static int getOffMinutes_abs(Date from, Date to) {
		return Math.abs((int) ((from.getTime() - to.getTime()) / 60000L));
	}

	/**
	 * 
	 * @param from
	 * @param to
	 * @return 相隔的秒钟
	 */
	public static int getOffSeconds_abs(Date from, Date to) {
		return Math.abs((int) ((from.getTime() - to.getTime()) / 1000L));
	}

	/**
	 * 以天的形式表示两个长整型数表示的时间间隔
	 * 
	 * @param from
	 *            开始的长整型数据
	 * @param to
	 *            结束的长整型数据
	 * @return 相隔的天数
	 */
	public static int getOffDays_abs(Date from, Date to) {
		return Math.abs((int) ((from.getTime() - to.getTime()) / (60000L * 60 * 24)));
	}

	/**
	 * 间隔几个月
	 * 
	 * @param from
	 * @param to
	 * @return
	 */
	public static int getOffMonths_abs(Date from, Date to) {
		Calendar bef = Calendar.getInstance();
		Calendar end = Calendar.getInstance();

		bef.setTime(from);
		end.setTime(to);

		int result = end.get(Calendar.MONTH) - bef.get(Calendar.MONTH);
		int month = (end.get(Calendar.YEAR) - bef.get(Calendar.YEAR)) * 12;
		// System.out.println(Math.abs(month + result));

		return Math.abs(month + result);
	}

	/**
	 * 间隔几个月
	 * 
	 * @param from
	 * @param to
	 * @return
	 */
	public static int getOffYear_abs(Date from, Date to) {
		Calendar bef = Calendar.getInstance();
		Calendar end = Calendar.getInstance();

		bef.setTime(from);
		end.setTime(to);

		int result = end.get(Calendar.YEAR) - bef.get(Calendar.YEAR);
		// int month = (end.get(Calendar.YEAR) - bef.get(Calendar.YEAR)) * 12;
		// System.out.println(Math.abs(month + result));

		return result;
	}

	/**
	 * 比对两个日期的大小
	 * 
	 * @param DATE1
	 * @param DATE2
	 * @return 1：DATE1大于DATE2 -1：DATE1小于DATE2 0：相等
	 */
	public static int compare_date(Date DATE1, Date DATE2) {
		try {
			Calendar bef = Calendar.getInstance();
			Calendar end = Calendar.getInstance();

			bef.setTime(DATE1);
			end.setTime(DATE2);
			if (bef.getTime().getTime() > end.getTime().getTime()) {
				return 1;
			} else if (bef.getTime().getTime() < end.getTime().getTime()) {
				return -1;
			} else {
				return 0;
			}
		} catch (Exception exception) {
			exception.printStackTrace();
		}
		return 0;
	}

	/**
	 * add by @author chengxp 获取writeInDate 距离 当前多久 超过一天 年月日 时分秒表示,一天内按时分表示
	 * 
	 * @param writeInDate
	 * @return XX年XX月XX日 .../XX时XX分前/XX分前
	 */
	public static String getDistanceCurTime(Date writeInDate) {

		String curTime = "";

		if (null == writeInDate) {

			return curTime;
		}

		// 此条数据毫秒数
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(writeInDate);
		Long pastTimeInMillis = calendar.getTimeInMillis();

		// 当前毫秒数
		Long curTimeInMillis = System.currentTimeMillis();

		// 一分钟的毫秒数
		Long minutesTimeInMillis = 60L * 1000L;

		// 一小时的毫秒数
		Long hoursTimeInMillis = 3600 * 1000L;

		// 一天的毫秒数
		Long daysTimeInMillis = 24 * hoursTimeInMillis;

		// 差值
		Long gapTimeInMillis = curTimeInMillis - pastTimeInMillis;

		// 大于一天按yyyy-MM-dd HH:mm:ss表示
		if (gapTimeInMillis >= daysTimeInMillis) {

			curTime = DateUtils.format(writeInDate, "yyyy-MM-dd HH:mm:ss");
			// 否则按时分表示
		} else {

			// 时
			if (gapTimeInMillis >= hoursTimeInMillis) {

				Long hours = gapTimeInMillis / hoursTimeInMillis;
				Long minutes = gapTimeInMillis % hoursTimeInMillis / minutesTimeInMillis;

				curTime = String.valueOf(hours + "小时 " + minutes + "分钟前");
				// 分
			} else {

				curTime = String.valueOf(gapTimeInMillis / minutesTimeInMillis) + "分钟前";
			}

		}
		return curTime;
	}

	/**
	 * 
	 * @param startTime
	 *            开始时间
	 * @param hours
	 *            持续时间
	 * @return
	 */
	public static Date getTime(Date startTime, int hours) {

		Calendar calendar = Calendar.getInstance();
		calendar.setTime(startTime);
		calendar.add(Calendar.HOUR_OF_DAY, hours);
		return calendar.getTime();
	}

	/**
	 * 得到历史时间
	 * 
	 * @param currTime
	 *            当前时间
	 * @param type
	 *            取历史时间的类型 Calendar.YEAR
	 * @param num
	 *            历史数量 天、年、月
	 * @return
	 */
	public static Date getHistoryTime(Date currTime, int type, int num) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(currTime);
		calendar.add(type, -num);// 当前时间减去一年，即一年前的时间
		return calendar.getTime();// 获取一年前的时间，或者一个月前的时间
	}

	/**
	 * 参数时间归属哪个季度，返回季度1、2、3、4
	 * 
	 * @param currTime
	 * @return
	 */
	public static int getQuarterByNowDate(Date currTime) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(currTime);
		int month = calendar.get(calendar.MONTH) + 1;
		int querter = 0;
		switch (month) {
		case 1:
			querter = 1;
			break;
		case 2:
			querter = 1;
			break;
		case 3:
			querter = 1;
			break;
		case 4:
			querter = 2;
			break;
		case 5:
			querter = 2;
			break;
		case 6:
			querter = 2;
			break;
		case 7:
			querter = 3;
			break;
		case 8:
			querter = 3;
			break;
		case 9:
			querter = 3;
			break;
		case 10:
			querter = 4;
			break;
		case 11:
			querter = 4;
			break;
		case 12:
			querter = 4;
			break;
		default:
			break;
		}
		return querter;
	}

	/**
	 * 毫秒时间格式化
	 *
	 * @param ms
	 * @return 返回类型 String
	 */
	public static final String formatTime(long begin, long end) {
		if (begin > end) return "";
		long ms = end - begin;
		int ss = 1000;
		int mi = ss * 60;
		int hh = mi * 60;
		int dd = hh * 24;
		long day = ms / dd;
		long hour = (ms - day * dd) / hh;
		long minute = (ms - day * dd - hour * hh) / mi;
		long second = (ms - day * dd - hour * hh - minute * mi) / ss;
		long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;
		String strDay = day < 10 ? "0" + day : "" + day; // 天
		String strHour = hour < 10 ? "0" + hour : "" + hour;// 小时
		String strMinute = minute < 10 ? "0" + minute : "" + minute;// 分钟
		String strSecond = second < 10 ? "0" + second : "" + second;// 秒
		String strMilliSecond = milliSecond < 10 ? "0" + milliSecond : "" + milliSecond;// 毫秒
		strMilliSecond = milliSecond < 100 ? "0" + strMilliSecond : "" + strMilliSecond;
		return strMinute + " 分钟 " + strSecond + " 秒" + strMilliSecond + "毫秒";
	}

	public static void main(String[] args) {
		System.out.println(format(getLastMonthStart(7), DATE_PATTERN.YYYY_MM_DD_HH_MM_SS));
	}
}